package main

import (
	"fmt"
	log "github.com/sirupsen/logrus"
	"os"
	"os/signal"
	"syscall"
	"time"
)

type Consumer interface {
	Shutdown() error
}
type consumer struct {
}

func (c *consumer) Shutdown() error {
	fmt.Println("退出")
	return nil
}

var consumerList = make([]Consumer, 0, 0)

func main() {
	PushConsumerSubscribe()
	PushConsumerSubscribe()
	time.Sleep(time.Second * 20)
}

func PushConsumerSubscribe() {
	registerShutdown(&consumer{})
}

func registerShutdown(c Consumer) {
	consumerList = append(consumerList, c)
}

func shutdown(c Consumer) {
	fmt.Println("shutdown")
	defer func() {
		if err := recover(); err != nil {
			log.Error("consumer关闭异常,consumer:%v,err:%v", c, err)
		}
	}()

	err := c.Shutdown()
	if err != nil {
		log.Error("consumer关闭失败,consumer:%v,err:%v", c, err)
	}
}

func shutdownAll() {
	for _, c := range consumerList {
		shutdown(c)
	}
}

func init() {
	fmt.Println("-------")
	sign := make(chan os.Signal, 1)
	//监听系统信号
	//syscall.SIGINT 监听 ctrl+c的退出，go run 方式和编译为可执行文件都可用
	//syscall.SIGTERM  是监听的kill 方式，go run 方式不可用，编译为可执行文件可用
	signal.Notify(sign, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	go func() {
		_ = <-sign
		shutdownAll()
	}()
}
